<template>
  <view class="sign-container">
    <!-- 顶部信息 -->
    <view class="top-info">
      <view class="beans-info">
        <text class="beans-count">{{totalBeans}}欢乐豆</text>
      </view>
      <view class="exchange-btn" @click="goToVip">
        <text>兑换会员</text>
      </view>
      <view class="sign-info">
        <text class="sign-days">连续签到{{continuousSignDays}}天</text>
      </view>
    </view>

    <!-- 签到卡片 -->
    <view class="sign-card">
      <!-- 月份选择 -->
      <view class="month-selector">
        <text class="arrow" @click="changeMonth(-1)">◀</text>
        <text class="current-month">{{currentYear}}年{{currentMonth}}月</text>
        <text class="arrow" @click="changeMonth(1)">▶</text>
      </view>

      <!-- 星期表头 -->
      <view class="calendar-header">
        <view class="week-item" v-for="day in ['日','一','二','三','四','五','六']" :key="day">{{day}}</view>
      </view>
      
      <!-- 日历主体 -->
      <view class="calendar">
        <view class="calendar-row" v-for="(week, weekIndex) in calendarDays" :key="weekIndex">
          <view 
            class="calendar-item" 
            v-for="(day, dayIndex) in week" 
            :key="dayIndex"
            :class="{
              'signed': day.signed,
              'today': day.isToday,
              'other-month': !day.currentMonth,
              'can-sign': day.canSign,
              'can-makeup': day.canMakeup,
              'missedSign': day.missedSign
            }"
            @click="day.canMakeup ? showMakeupDialog(day) : null"
          >
            <text class="day-text">{{day.date}}</text>
            <text class="beans-text" v-if="day.signed">+5</text>
          </view>
        </view>
      </view>

      <!-- 签到按钮 -->
      <view class="sign-action">
        <button 
          class="sign-btn" 
          :class="{'signed-btn': todaySigned}"
          @click="handleSign"
        >
          {{todaySigned ? '今日已签到 +5欢乐豆' : '立即签到'}}
        </button>
      </view>

      <!-- 补签卡信息 -->
      <view class="makeup-card">
        <view class="makeup-info">
          <view class="makeup-count">
            <text class="label">补签卡：</text>
            <text class="value">{{ Math.max(0, makeupCards) }}张</text>
          </view>
          <text class="makeup-tip">点击未签到日期可使用补签卡</text>
        </view>
        <text class="makeup-tip">连续签到5天可获得1张补签卡</text>
      </view>
    </view>

    <!-- 签到规则 -->
    <view class="sign-rules">
      <view class="rules-header">
        <text>签到规则</text>
      </view>
      <view class="rules-content">
        <text>1. 每日签到可获得5欢乐豆</text>
        <text>2. 连续签到5天可获得1张补签卡</text>
        <text>3. 补签卡可用于补签漏签的日期</text>
        <text>4. 使用补签卡后可保持连续签到天数</text>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      userId: 1, // 开发测试时直接使用固定的userId
      totalBeans: 0,
      continuousSignDays: 0,
      todaySigned: false,
      makeupCards: 0,
      currentYear: new Date().getFullYear(),
      currentMonth: new Date().getMonth() + 1,
      calendarDays: [],
      signedDays: [],
      selectedMakeupDate: null,
      signRecord: {},
    }
  },
  async created() {
    await this.getSignInfo()
    await this.fetchMonthSignRecord(this.currentYear, this.currentMonth)
    this.initCalendar()
  },
  methods: {
    // 获取签到信息
    async getSignInfo() {
      try {
        const res = await uni.request({
          url: `http://localhost:9224/sign/info?userId=${this.userId}`,
          method: 'GET'
        })
        if (res.data.code === 200) {
          const signInfo = res.data.data
          this.totalBeans = signInfo.num
          this.makeupCards = Math.max(0, signInfo.signNum)
          this.continuousSignDays = signInfo.continuousDays || 0
          const lastSignTime = new Date(signInfo.updateTime)
          const today = new Date()
          this.todaySigned = lastSignTime.getDate() === today.getDate() &&
                            lastSignTime.getMonth() === today.getMonth() &&
                            lastSignTime.getFullYear() === today.getFullYear()
          this.initCalendar()
        } else {
          uni.showToast({
            title: res.data.msg || '获取签到信息失败',
            icon: 'none'
          })
        }
      } catch (error) {
        uni.showToast({
          title: '获取签到信息失败',
          icon: 'none'
        })
      }
    },

    // 执行签到
    async handleSign() {
      if (this.todaySigned) {
        uni.showToast({
          title: '今天已经签到过了',
          icon: 'none'
        })
        return
      }
      try {
        const res = await uni.request({
          url: `http://localhost:9224/sign/doSign?userId=${this.userId}`,
          method: 'POST'
        })
        if (res.data.code === 200) {
          const data = res.data.data
          this.todaySigned = true
          this.totalBeans = data.num
          this.makeupCards = Math.max(0, data.signNum)
          this.continuousSignDays = data.continuousDays || 0
          // 添加今天的签到记录
          const today = new Date()
          const key = `${this.currentYear}-${this.currentMonth}`
          if (!this.signRecord[key]) {
            this.signRecord[key] = []
          }
          this.signRecord[key].push(today.getDate())
          this.initCalendar()
          // 新增：补签卡获得弹窗
          if (data.makeupCardAwarded) {
            uni.showModal({
              title: '恭喜获得补签卡',
              content: '连续签到5天，奖励1张补签卡！',
              showCancel: false
            })
          } else {
            uni.showToast({
              title: res.data.msg || '签到成功',
              icon: 'success'
            })
          }
        } else {
          uni.showToast({
            title: res.data.msg || '签到失败',
            icon: 'none'
          })
        }
      } catch (error) {
        uni.showToast({
          title: '签到失败',
          icon: 'none'
        })
      }
    },

    // 跳转到VIP页面
    goToVip() {
      uni.navigateTo({
        url: '/pages/sign/vip'
      })
    },

    // 获取当前月份的签到记录（返回对象数组）
    getMonthSignRecord(year, month) {
      const key = `${year}-${month}`
      return this.signRecord[key] || []
    },

    // 添加签到记录
    addSignRecord(year, month, day) {
      const key = `${year}-${month}`
      if (!this.signRecord[key]) {
        this.signRecord[key] = []
      }
      if (!this.signRecord[key].includes(day)) {
        this.signRecord[key].push(day)
      }
    },

    // 获取某月所有签到天数
    async fetchMonthSignRecord(year, month) {
      try {
        const res = await uni.request({
          url: `http://localhost:9224/sign/monthRecord?userId=${this.userId}&year=${year}&month=${month}`,
          method: 'GET'
        })
        if (res.data.code === 200) {
          const key = `${year}-${month}`
          this.signRecord[key] = res.data.data || []
        }
      } catch (e) {
        // 忽略错误
      }
    },

    // 初始化日历数据
    async initCalendar() {
      const year = this.currentYear
      const month = this.currentMonth
      await this.fetchMonthSignRecord(year, month)
      const firstDay = new Date(year, month - 1, 1)
      const lastDay = new Date(year, month, 0)
      const totalDays = lastDay.getDate()
      const firstDayWeek = firstDay.getDay()
      let days = []
      let week = []
      const prevMonthLastDay = new Date(year, month - 1, 0).getDate()
      for (let i = 0; i < firstDayWeek; i++) {
        week.push({
          date: prevMonthLastDay - firstDayWeek + i + 1,
          signed: false,
          isToday: false,
          currentMonth: false,
          canSign: false,
          canMakeup: false,
          status: 0
        })
      }
      // 获取当前月份的签到记录（带status）
      const currentMonthRecord = this.getMonthSignRecord(year, month)
      // 构建一个map方便查找
      const statusMap = {}
      currentMonthRecord.forEach(item => {
        statusMap[item.day] = item.status
      })
      const today = new Date()
      const isCurrentMonth = today.getFullYear() === year && today.getMonth() === month - 1
      const currentDate = today.getDate()
      for (let i = 1; i <= totalDays; i++) {
        const isToday = isCurrentMonth && currentDate === i
        const status = statusMap[i] !== undefined ? statusMap[i] : 0
        const isSigned = status === 1
        // 只有status=0的日期才允许补签
        const canMakeup = status === 0 && this.makeupCards > 0 && i < currentDate && isCurrentMonth
        week.push({
          date: i,
          signed: isSigned,
          isToday: isToday,
          currentMonth: true,
          canSign: isToday && !this.todaySigned,
          canMakeup: canMakeup,
          missedSign: status === 0 && i < currentDate && isCurrentMonth,
          status: status
        })
        if (week.length === 7) {
          days.push(week)
          week = []
        }
      }
      if (week.length > 0) {
        const nextMonthDays = 7 - week.length
        for (let i = 1; i <= nextMonthDays; i++) {
          week.push({
            date: i,
            signed: false,
            isToday: false,
            currentMonth: false,
            canSign: false,
            canMakeup: false,
            status: 0
          })
        }
        days.push(week)
      }
      this.calendarDays = days
    },

    // 判断日期是否可以补签
    canMakeup(date) {
      const today = new Date()
      const currentDate = today.getDate()
      const currentMonth = today.getMonth() + 1
      const currentYear = today.getFullYear()
      
      // 只能补签本月之前的未签到日期
      return (
        this.makeupCards > 0 && // 有补签卡
        !this.getMonthSignRecord(this.currentYear, this.currentMonth).includes(date) && // 未签到
        (
          // 只能补签本月之前的日期
          (this.currentYear === currentYear && this.currentMonth === currentMonth && date < currentDate) ||
          // 或者之前月份的日期
          (this.currentYear === currentYear && this.currentMonth < currentMonth) ||
          this.currentYear < currentYear
        )
      )
    },
    
    // 计算连续签到天数
    calculateContinuousSignDays() {
      const today = new Date()
      const currentYear = today.getFullYear()
      const currentMonth = today.getMonth() + 1
      const currentDate = today.getDate()
      
      let count = 0
      let checkDate = currentDate
      let checkMonth = currentMonth
      let checkYear = currentYear
      
      // 从今天开始往前查找连续签到记录
      while (true) {
        const record = this.getMonthSignRecord(checkYear, checkMonth)
        
        // 如果当前检查的日期不在签到记录中，结束查找
        if (!record.includes(checkDate)) {
          break
        }
        
        count++
        checkDate--
        
        // 如果检查到月初，需要切换到上个月
        if (checkDate === 0) {
          checkMonth--
          if (checkMonth === 0) {
            checkMonth = 12
            checkYear--
          }
          // 获取上个月的最后一天
          checkDate = new Date(checkYear, checkMonth, 0).getDate()
        }
      }
      
      this.continuousSignDays = count
    },
    
    // 切换月份
    async changeMonth(delta) {
      let newMonth = this.currentMonth + delta
      let newYear = this.currentYear
      if (newMonth > 12) {
        newMonth = 1
        newYear++
      } else if (newMonth < 1) {
        newMonth = 12
        newYear--
      }
      this.currentMonth = newMonth
      this.currentYear = newYear
      await this.fetchMonthSignRecord(newYear, newMonth)
      this.initCalendar()
    },
    
    // 显示补签对话框
    showMakeupDialog(day) {
      if (!day.canMakeup) {
        if (this.makeupCards === 0) {
          uni.showToast({
            title: '暂无补签卡',
            icon: 'none'
          })
        } else {
          uni.showToast({
            title: '该日期不可补签',
            icon: 'none'
          })
        }
        return
      }
      
      this.selectedMakeupDate = day.date
      uni.showModal({
        title: '使用补签卡',
        content: `确定要补签${this.currentMonth}月${day.date}日吗？`,
        success: (res) => {
          if (res.confirm) {
            this.useMakeupCard()
          }
        }
      })
    },
    
    // 使用补签卡
    async useMakeupCard() {
      if (!this.selectedMakeupDate) return
      
      try {
        const result = await this.makeupSign(this.selectedMakeupDate)
        if (result) {
          this.makeupCards--
          this.addSignRecord(this.currentYear, this.currentMonth, this.selectedMakeupDate)
          this.totalBeans += 5
          
          // 重新计算连续签到天数
          this.calculateContinuousSignDays()
          
          uni.showToast({
            title: '补签成功 +5欢乐豆',
            icon: 'success'
          })
          
          this.selectedMakeupDate = null
          // 更新日历
          this.initCalendar()
        }
      } catch (error) {
        uni.showToast({
          title: '补签失败，请重试',
          icon: 'none'
        })
      }
    },
    
    // 补签接口
    async makeupSign(date) {
      try {
        const year = this.currentYear
        const month = this.currentMonth
        // 格式化日期 yyyy-MM-dd
        const dateStr = `${year}-${String(month).padStart(2, '0')}-${String(date).padStart(2, '0')}`
        const res = await uni.request({
          url: `http://localhost:9224/sign/makeupSign`,
          method: 'POST',
          header: { 'content-type': 'application/x-www-form-urlencoded' },
          data: {
            userId: this.userId,
            date: dateStr
          }
        })
        if (res.data.code === 200) {
          // 刷新签到信息和日历
          await this.getSignInfo()
          await this.fetchMonthSignRecord(year, month)
          this.initCalendar()
          uni.showToast({
            title: '补签成功 +5欢乐豆',
            icon: 'success'
          })
          return true
        } else {
          uni.showToast({
            title: res.data.msg || '操作失败',
            icon: 'none'
          })
          return false
        }
      } catch (error) {
        uni.showToast({
          title: '补签失败，请重试',
          icon: 'none'
        })
        return false
      }
    }
  },
  
  mounted() {
    this.initCalendar()
    this.calculateContinuousSignDays()
  }
}
</script>

<style lang="scss" scoped>
.sign-container {
  padding: 20rpx;
  background-color: #f5f5f5;
  min-height: 100vh;
  
  .top-info {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 30rpx;
    background-color: #fff;
    border-radius: 16rpx;
    margin-bottom: 20rpx;
    
    .beans-info {
      .beans-count {
        font-size: 40rpx;
        font-weight: bold;
        color: #ff6b6b;
      }
    }
    
    .exchange-btn {
      padding: 10rpx 30rpx;
      background: linear-gradient(135deg, #ff6b6b, #ff8e8e);
      border-radius: 30rpx;
      box-shadow: 0 4rpx 12rpx rgba(255, 107, 107, 0.3);
      
      text {
        color: #fff;
        font-size: 28rpx;
        font-weight: bold;
      }
    }
    
    .sign-info {
      .sign-days {
        font-size: 28rpx;
        color: #666;
      }
    }
  }
  
  .sign-card {
    background-color: #fff;
    border-radius: 16rpx;
    padding: 30rpx;
    margin-bottom: 20rpx;
    
    .month-selector {
      display: flex;
      justify-content: center;
      align-items: center;
      margin-bottom: 30rpx;
      
      .arrow {
        padding: 20rpx;
        color: #666;
        font-size: 28rpx;
      }
      
      .current-month {
        font-size: 32rpx;
        font-weight: bold;
        margin: 0 40rpx;
      }
    }
    
    .calendar-header {
      display: grid;
      grid-template-columns: repeat(7, 1fr);
      margin-bottom: 20rpx;
      
      .week-item {
        text-align: center;
        font-size: 28rpx;
        color: #999;
        padding: 10rpx 0;
      }
    }
    
    .calendar {
      .calendar-row {
        display: grid;
        grid-template-columns: repeat(7, 1fr);
        margin-bottom: 20rpx;
        
        .calendar-item {
          position: relative;
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          height: 90rpx;
          
          &.signed {
            .day-text {
              color: #fff;
            }
            
            &::after {
              content: '';
              position: absolute;
              top: 50%;
              left: 50%;
              transform: translate(-50%, -50%);
              width: 70rpx;
              height: 70rpx;
              background-color: #4CAF50;
              border-radius: 50%;
              z-index: 0;
            }
          }
          
          &.missedSign {
            .day-text {
              color: #fff;
            }
            
            &::after {
              content: '';
              position: absolute;
              top: 50%;
              left: 50%;
              transform: translate(-50%, -50%);
              width: 70rpx;
              height: 70rpx;
              background-color: #ff6b6b;
              border-radius: 50%;
              z-index: 0;
            }
          }
          
          &.today {
            .day-text {
              font-weight: bold;
            }
            
            &::before {
              content: '';
              position: absolute;
              top: 50%;
              left: 50%;
              transform: translate(-50%, -50%);
              width: 76rpx;
              height: 76rpx;
              border: 2rpx solid #4CAF50;
              border-radius: 50%;
            }
          }
          
          &.can-makeup {
            cursor: pointer;
            
            &::after {
              content: '';
              position: absolute;
              top: 50%;
              left: 50%;
              transform: translate(-50%, -50%);
              width: 70rpx;
              height: 70rpx;
              border: 2rpx dashed #ff6b6b;
              border-radius: 50%;
              opacity: 0.5;
            }
            
            &:hover {
              .day-text {
                color: #ff6b6b;
              }
              
              &::after {
                opacity: 1;
              }
            }
          }
          
          &.other-month {
            .day-text {
              color: #ccc;
            }
          }
          
          .day-text {
            font-size: 32rpx;
            line-height: 1;
            z-index: 1;
            color: #333;
          }
          
          .beans-text {
            font-size: 20rpx;
            color: #fff;
            margin-top: 8rpx;
            z-index: 1;
          }
        }
      }
    }
    
    .sign-action {
      margin: 30rpx 0;
      
      .sign-btn {
        width: 100%;
        height: 88rpx;
        line-height: 88rpx;
        text-align: center;
        background: linear-gradient(135deg, #4CAF50, #45a049);
        color: #fff;
        border-radius: 44rpx;
        font-size: 32rpx;
        font-weight: bold;
        box-shadow: 0 4rpx 12rpx rgba(76, 175, 80, 0.3);
        
        &.signed-btn {
          background: #ccc;
          box-shadow: none;
        }
      }
    }
    
    .makeup-card {
      .makeup-info {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 10rpx;
        
        .makeup-count {
          .label {
            font-size: 28rpx;
            color: #666;
          }
          
          .value {
            font-size: 28rpx;
            color: #4CAF50;
            font-weight: bold;
          }
        }
        
        .makeup-tip {
          font-size: 24rpx;
          color: #999;
        }
      }
      
      .makeup-tip {
        font-size: 24rpx;
        color: #999;
      }
    }
  }
  
  .sign-rules {
    background-color: #fff;
    border-radius: 16rpx;
    padding: 30rpx;
    
    .rules-header {
      font-size: 32rpx;
      font-weight: bold;
      margin-bottom: 20rpx;
      
      &::before {
        content: '';
        display: inline-block;
        width: 6rpx;
        height: 32rpx;
        background-color: #4CAF50;
        margin-right: 16rpx;
        vertical-align: middle;
      }
    }
    
    .rules-content {
      text {
        display: block;
        font-size: 28rpx;
        color: #666;
        margin-bottom: 10rpx;
        padding-left: 30rpx;
        position: relative;
        
        &::before {
          content: '';
          position: absolute;
          left: 10rpx;
          top: 50%;
          transform: translateY(-50%);
          width: 6rpx;
          height: 6rpx;
          border-radius: 50%;
          background-color: #4CAF50;
        }
      }
    }
  }
}
</style> 